package ar.uba.fi.tonyvaliente.documents;

import java.util.NoSuchElementException;

import ar.uba.fi.tonyvaliente.files.File;
import ar.uba.fi.tonyvaliente.files.FileException;
import ar.uba.fi.tonyvaliente.persistors.IntegerPersistor;
import ar.uba.fi.tonyvaliente.tree.BTreeException;
import ar.uba.fi.tonyvaliente.tree.DiskBTree;
import ar.uba.fi.tonyvaliente.utils.RecursosAplicacion;

public class DocumentHashing {

	private static final String DOCS_ROOT = RecursosAplicacion.instance().getProperty("docs.root");
	
	private static final String defaultDataPath = DOCS_ROOT + "/document_hash.data";
	private static final String defaultPropPath = DOCS_ROOT + "/document_hash.prop";
	private String dataPath;
	private String propPath;
	private DiskBTree<Integer,DocumentInfo> dataPersistence;
	private File propPersistence;

	public DocumentHashing() {
		this(defaultDataPath, defaultPropPath);
	}

	private DocumentHashing(String dataPath, String propPath) {
		this.dataPath = dataPath;
		this.propPath = propPath;
	}

	public void initilize() throws Exception {
		ensureDelete();

		dataPersistence = new DiskBTree<Integer, DocumentInfo>(20, dataPath,
				new IntegerPersistor(), new DocumentInfoPersistor());
		dataPersistence.close();
		propPersistence = File.create(propPath, 512);
		propPersistence.setProperty("lastDocumentId", "0");
		propPersistence.flush();
	}

	public int addDocument(String documentHash, String documentTitle) {
		ensurePersitence();
		String lastDocumentId = propPersistence.getProperty("lastDocumentId");
		int newDocumentId = Integer.parseInt(lastDocumentId) + 1;
		try {
			propPersistence.setProperty("lastDocumentId", new Integer(newDocumentId).toString());
			propPersistence.flush();
		} catch (FileException e) {
			e.printStackTrace();
		}

		try {
			dataPersistence.add(newDocumentId, new DocumentInfo(documentHash, documentTitle));
		} catch (BTreeException e) {
			e.printStackTrace();
		}

		return newDocumentId;
	}

	public DocumentInfo getDocumentInfo(int documentId) {
		ensurePersitence();
		try {
			DocumentInfo info = dataPersistence.get(new Integer(documentId));
			return info;
		} catch (NoSuchElementException e) {
			e.printStackTrace();
		} catch (BTreeException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public int getDocumentCount() {
		try {
			return Integer.parseInt(this.propPersistence.getProperty("lastDocumentId"));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	public void close() {
		try {
			this.dataPersistence.close();
			this.propPersistence.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void ensureDelete() {
		java.io.File file;

		file = new java.io.File(dataPath);
		if (file.exists())
			file.delete();
		file = new java.io.File(propPath);
		if (file.exists())
			file.delete();
	}

	public void ensurePersitence() {
		try {
			if (dataPersistence == null) {
			dataPersistence = new DiskBTree<Integer, DocumentInfo>(dataPath, false,
					new IntegerPersistor(), new DocumentInfoPersistor());
			}
		} catch (BTreeException e) {
			e.printStackTrace();
		}

		try {
			if (propPersistence == null) {
			propPersistence = File.open(propPath, false);
			}
		} catch (FileException e) {
			e.printStackTrace();
		}
	}
}
